メインコンテンツまでスキップ

AKS Workload Identity

Azure Kubernetes Service (AKS) における認証機能について、Workload Identity、Managed Identity、User-Assigned Identity の概念と使い方を解説します。

概要

AKS上で動作するワークロード(Pod)が Azure リソースにアクセスする際、安全に認証するための仕組みが必要です。Azure では以下のような Identity 機能を提供しています。

Managed Identity とは

Managed Identity は、Azure AD (現在の Microsoft Entra ID) が管理する ID で、アプリケーションが Azure サービスへ認証する際にシークレットを管理する必要がなくなる機能です。

Managed Identity の種類

1. System-Assigned Managed Identity (システム割り当てマネージド ID)

  • Azure リソース(VM、App Service、AKS など)に直接紐づく ID
  • リソースのライフサイクルと連動(リソースを削除すると ID も削除される)
  • 1つのリソースに1つの ID のみ
  • 簡単に有効化できる

利点:

  • 管理が容易
  • リソースと ID のライフサイクルが一致

制限:

  • 複数のリソースで同じ ID を共有できない

2. User-Assigned Managed Identity (ユーザー割り当てマネージド ID)

  • Azure リソースとは独立した ID リソースとして作成
  • 複数の Azure リソースに同じ ID を割り当て可能
  • ID のライフサイクルを独自に管理

利点:

  • 複数のリソースで同じ ID を共有可能
  • リソースを削除しても ID は残る
  • より柔軟な管理が可能

使用例:

  • 複数の AKS クラスタで同じ Azure リソースにアクセスする場合
  • 開発/ステージング/本番環境で同じ ID を使いたい場合

Workload Identity フェデレーション

Workload Identity フェデレーションは、Microsoft Entra の機能の一つで、ソフトウェアワークロードがシークレットや証明書を管理することなく、Microsoft Entra で保護されたリソースに安全にアクセスできるようにする仕組みです。 AKS Workload Identity は、この Workload Identity フェデレーションの仕組みを AKS (Kubernetes) に適用したものです。

導入のメリット

通常、Azure 外部や Kubernetes 上のアプリケーションが Azure リソースにアクセスする場合、シークレット(パスワードや API キー)の管理が必要でした。しかし、シークレットには漏洩や有効期限切れのリスクがあります。 Workload Identity フェデレーションを使用すると、以下のメリットがあります:

  • シークレット不要: 資格情報を保存・管理する必要がなくなります。
  • セキュリティ向上: 外部 ID プロバイダー (IdP) のトークンを信頼する仕組みのため、漏洩リスクが低減します。
  • 運用負荷の軽減: シークレットのローテーションや証明書の更新作業が不要になります。

サポートされるシナリオ

Workload Identity フェデレーションは、AKS だけでなく、以下のような多様なシナリオで使用できます:

  • Kubernetes: AKS、EKS (AWS)、GKE (Google Cloud)、オンプレミスなど
  • CI/CD: GitHub Actions, Azure Pipelines など
  • 他のクラウド: Google Cloud, AWS 上で動作するワークロード
  • オンプレミス: Azure 外部で動作するサービス

仕組み (概要)

Microsoft Entra ID の ユーザー割り当てマネージド ID (またはアプリ登録) と、外部の ID プロバイダー (IdP) との間に信頼関係 (Federated Identity Credential) を設定します。

  1. 外部ワークロードが外部 IdP からトークンを取得
  2. そのトークンを Microsoft Entra ID に提示
  3. Microsoft Entra ID が信頼関係を検証し、アクセストークンを発行
  4. アクセストークンを使って Azure リソースへアクセス

AKS Workload Identity

Workload Identity は、AKS の Pod に対して Managed Identity を安全に割り当てる仕組みです。

従来の方法の課題

以前は Pod に Identity を割り当てる方法として Azure AD Pod Identity が使われていましたが、以下のような課題がありました:

  • 複雑なアーキテクチャ
  • セキュリティ上の懸念
  • メンテナンスの負担

Workload Identity の仕組み

Workload Identity は OpenID Connect (OIDC) を使用して、Kubernetes Service Account と Azure Managed Identity を連携させます。

フロー:

  1. Pod が Kubernetes Service Account に紐づけられる
  2. Service Account が OIDC トークンを発行
  3. OIDC トークンを Azure AD に提示
  4. Azure AD が検証し、Azure リソースへのアクセストークンを発行
  5. Pod が Azure リソースにアクセス

Workload Identity の利点

  • セキュリティ向上: ノードに権限を付与する必要がなく、Pod レベルで細かく制御可能
  • Kubernetes ネイティブ: Service Account という Kubernetes の標準機能を使用
  • シンプルな管理: 従来の Pod Identity より管理が容易
  • 業界標準: OIDC を使用したクラウドネイティブなアプローチ

設定方法

1. AKS クラスタで Workload Identity を有効化

# 新規クラスタの作成
az aks create \
--resource-group myResourceGroup \
--name myAKSCluster \
--enable-oidc-issuer \
--enable-workload-identity

# 既存クラスタの更新
az aks update \
--resource-group myResourceGroup \
--name myAKSCluster \
--enable-oidc-issuer \
--enable-workload-identity

2. User-Assigned Managed Identity の作成

# Managed Identity の作成
az identity create \
--name myIdentity \
--resource-group myResourceGroup \
--location eastus

# Client ID の取得
export USER_ASSIGNED_CLIENT_ID=$(az identity show \
--resource-group myResourceGroup \
--name myIdentity \
--query 'clientId' -o tsv)

3. Azure リソースへのアクセス権限付与

# Storage Account へのアクセス権限を付与する例
az role assignment create \
--role "Storage Blob Data Contributor" \
--assignee $USER_ASSIGNED_CLIENT_ID \
--scope /subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.Storage/storageAccounts/<storage-account>

4. Kubernetes Service Account の作成

apiVersion: v1
kind: ServiceAccount
metadata:
name: workload-identity-sa
namespace: default
annotations:
azure.workload.identity/client-id: "${USER_ASSIGNED_CLIENT_ID}"

5. Federated Credential の作成

# OIDC Issuer URL の取得
export AKS_OIDC_ISSUER=$(az aks show \
--resource-group myResourceGroup \
--name myAKSCluster \
--query "oidcIssuerProfile.issuerUrl" -o tsv)

# Federated Credential の作成
az identity federated-credential create \
--name myFederatedIdentity \
--identity-name myIdentity \
--resource-group myResourceGroup \
--issuer "${AKS_OIDC_ISSUER}" \
--subject system:serviceaccount:default:workload-identity-sa

6. Pod での使用

apiVersion: v1
kind: Pod
metadata:
name: workload-identity-pod
namespace: default
labels:
azure.workload.identity/use: "true"
spec:
serviceAccountName: workload-identity-sa
containers:
- name: app
image: mcr.microsoft.com/azure-cli
command: ["sleep", "infinity"]

実装例

Azure Storage へのアクセス

from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient

# Workload Identity を使用して自動的に認証
credential = DefaultAzureCredential()
blob_service_client = BlobServiceClient(
account_url="https://<storage-account>.blob.core.windows.net",
credential=credential
)

# Blob の一覧を取得
container_client = blob_service_client.get_container_client("mycontainer")
blob_list = container_client.list_blobs()
for blob in blob_list:
print(blob.name)

Azure Key Vault へのアクセス

using Azure.Identity;
using Azure.Security.KeyVault.Secrets;

// Workload Identity を使用して自動的に認証
var credential = new DefaultAzureCredential();
var client = new SecretClient(
new Uri("https://<keyvault-name>.vault.azure.net/"),
credential
);

// シークレットの取得
KeyVaultSecret secret = await client.GetSecretAsync("my-secret");
Console.WriteLine($"Secret value: {secret.Value}");

トラブルシューティング

よくある問題

1. 認証エラー

症状: AADSTS700016: Application with identifier was not found in the directory

原因と対処:

  • Federated Credential の設定が正しくない
  • Service Account の annotations が正しくない
  • OIDC Issuer URL が正しくない

確認方法:

# Service Account の確認
kubectl get sa workload-identity-sa -o yaml

# Pod のラベル確認
kubectl get pod workload-identity-pod -o yaml | grep azure.workload.identity

2. 権限エラー

症状: 403 ForbiddenThis request is not authorized to perform this operation

原因と対処:

  • Managed Identity に適切なロール割り当てがされていない
  • ロールの伝播に時間がかかっている(最大5分程度待つ)

確認方法:

# ロール割り当ての確認
az role assignment list \
--assignee $USER_ASSIGNED_CLIENT_ID \
--all -o table

3. Pod が Identity を取得できない

原因:

  • Pod に azure.workload.identity/use: "true" ラベルがない
  • Service Account が正しく指定されていない

デバッグ方法:

# Pod 内で環境変数を確認
kubectl exec -it workload-identity-pod -- env | grep AZURE

# 以下の環境変数が設定されているか確認:
# - AZURE_CLIENT_ID
# - AZURE_TENANT_ID
# - AZURE_FEDERATED_TOKEN_FILE

ベストプラクティス

1. 最小権限の原則

必要最低限の権限のみを付与します。

# ❌ 悪い例: Contributor ロールを付与
az role assignment create \
--role "Contributor" \
--assignee $USER_ASSIGNED_CLIENT_ID

# ✅ 良い例: 特定の操作のみ許可
az role assignment create \
--role "Storage Blob Data Reader" \
--assignee $USER_ASSIGNED_CLIENT_ID \
--scope /subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.Storage/storageAccounts/<account>

2. Namespace の分離

環境や用途ごとに Namespace と Service Account を分けます。

# 開発環境用
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-sa
namespace: development
annotations:
azure.workload.identity/client-id: "${DEV_CLIENT_ID}"
---
# 本番環境用
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-sa
namespace: production
annotations:
azure.workload.identity/client-id: "${PROD_CLIENT_ID}"

3. Identity のライフサイクル管理

  • User-Assigned Managed Identity は再利用可能なリソースとして管理
  • Infrastructure as Code (Terraform, Bicep など) で管理
  • 定期的に使用状況を監査

4. モニタリングとログ

# Azure AD のサインインログを確認
az monitor activity-log list \
--resource-group myResourceGroup \
--offset 1h

# AKS のログを確認
kubectl logs -l azure.workload.identity/use=true -n default

まとめ

機能説明使用ケース
System-Assigned Managed Identityリソースに直接紐づく ID単一リソースでの使用
User-Assigned Managed Identity独立した ID リソース複数リソースでの共有
Workload IdentityPod に Identity を安全に付与AKS 上のアプリケーション

主な利点

  • シークレット管理が不要
  • セキュリティの向上
  • Kubernetes ネイティブな実装
  • 細かいアクセス制御

移行について

Azure AD Pod Identity から Workload Identity への移行が推奨されています。既存の Pod Identity を使用している場合は、計画的に移行を進めましょう。

参考リンク